﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace BuddHa.Common.CryptoOpex.RSAUtil.Implementation
{
    public abstract class RSAFormatter : IRSAFormatter
    {
        public string KeyFormat(string key, string formatString)
        {
            if (key.StartsWith($"-----BEGIN {formatString}-----"))
            {
                return key;
            }
            var keyList = new List<string>();
            keyList.Add($"-----BEGIN {formatString}-----");
            int pos = 0;

            while (pos < key.Length)
            {
                var count = key.Length - pos < 64 ? key.Length - pos : 64;
                keyList.Add(key.Substring(pos, count));
                pos += count;
            }
            keyList.Add($"-----END {formatString}-----");
            return string.Join("\r\n", keyList);
        }

        public string KeyFormatRemove(string key, string formatString)
        {
            if (!key.StartsWith($"-----BEGIN {formatString}-----"))
            {
                return key;
            }
            return key.Replace($"-----BEGIN  {formatString}-----", "").Replace($"-----END {formatString}-----", "")
                .Replace("\r\n", "");
        }

        RSA IRSAFormatter.CreateByPublicKey(string key, int size = (int)EnumRSAMode.RSA2)
        {
            var publicRSA = RSA.Create();
            publicRSA.KeySize = size;
            publicRSA.ImportParameters(CreateByPublicKey(key));
            return publicRSA;
        }

        RSA IRSAFormatter.CreateByPrivateKey(string key, int size = (int)EnumRSAMode.RSA2)
        {
            var privateRSA = RSA.Create();
            privateRSA.KeySize = size;
            privateRSA.ImportParameters(CreateByPrivateKey(key));
            return privateRSA;
        }

        RSA IRSAFormatter.ExportPublicKey(RSA privateRSA, RSAParameters? rsaPrivateParameters)
        {
            var publicRSA = RSA.Create();
            publicRSA.KeySize = privateRSA.KeySize;
            if (!rsaPrivateParameters.HasValue)
            {
                rsaPrivateParameters = privateRSA.ExportParameters(true);
            }
            var rsaParameters = new RSAParameters
            {
                Modulus = rsaPrivateParameters.Value.Modulus,
                Exponent = rsaPrivateParameters.Value.Exponent
            };
            return publicRSA;
        }

        protected abstract RSAParameters CreateByPublicKey(string key);

        protected abstract RSAParameters CreateByPrivateKey(string key);
    }
}
